--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_lilywhite = General:new(extension, "hy_lilywhite", "jin_k", 3, 3, General.Female)
    local spring_notify = fk.CreateSkill {
        name = "spring_notify",
    }
    spring_notify:addEffect(fk.CardUseFinished, {
        anim_type = "support",
        can_trigger = function(self, event, target, player, data)
            local choices = { "spring_notify_draw", "spring_notify_recover" }
            if player:getMark("spring_notify_draw-turn") > 0 then
                table.removeOne(choices, "spring_notify_draw")
            end
            if player:getMark("spring_notify_recover-turn") > 0 or #table.filter(player.room.alive_players, function(t)
                    return t:isWounded()
                end) == 0 then
                table.removeOne(choices, "spring_notify_recover")
            end
            return player:hasSkill(spring_notify.name) and target == player and data.card.suit == Card.Heart and #choices > 0
        end,
        on_cost = function(self, event, target, player)
            local room = player.room
            local choices = { "spring_notify_draw", "spring_notify_recover", "Cancel" }
            if player:getMark("spring_notify_draw-turn") > 0 then
                table.removeOne(choices, "spring_notify_draw")
            end
            if player:getMark("spring_notify_recover-turn") > 0 or #table.filter(room.alive_players, function(t)
                    return t:isWounded()
                end) == 0 then
                table.removeOne(choices, "spring_notify_recover")
            end
            event:setCostData(self, room:askToChoice(player, {
                choices = choices,
                skill_name = spring_notify.name
            }))
            return event:getCostData(self) ~= "Cancel"
        end,
        on_use = function(self, event, target, player)
            local room = player.room
            if event:getCostData(self) == "spring_notify_draw" then
                room:setPlayerMark(player, "spring_notify_draw-turn", 1)
                local skillTarget = room:askToChoosePlayers(player, {
                    targets = room.alive_players,
                    min_num = 1,
                    max_num = 1,
                    prompt = "spring_notify_draw_prompt",
                    skill_name = spring_notify.name,
                    cancelable = false
                })[1]
                if not skillTarget.dead then
                    room:drawCards(skillTarget, 2, spring_notify.name)
                end
            else
                room:setPlayerMark(player, "spring_notify_recover-turn", 1)
                local skillTarget = room:askToChoosePlayers(player, {
                    targets = table.filter(room.alive_players, function(t)
                        return t:isWounded()
                    end),
                    min_num = 1,
                    max_num = 1,
                    prompt = "spring_notify_recover_prompt",
                    skill_name = spring_notify.name,
                    cancelable = false
                })[1]
                if not skillTarget.dead then
                    room:recover({
                        who = skillTarget,
                        num = 1,
                        recoverBy = player,
                        skillName = spring_notify.name,
                    })
                end
            end
        end
    })
    local spring_interest = fk.CreateSkill {
        name = "spring_interest",
    }
    spring_interest:addEffect(fk.EventPhaseStart, {
        anim_type = "support",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(self) and player.phase == Player.Start and player:getMark("@spring_interest") >= 3
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            local room = player.room
            room:setPlayerMark(player, "@spring_interest", 0)
            room:changeMaxHp(player, 1)
        end,
    })
    local spring_coming = fk.CreateSkill {
        name = "spring_coming",
    }
    spring_coming:addEffect(fk.AfterCardsMove, {
        anim_type = "masochism",
        can_trigger = function(self, event, target, player, data)
            if not player:hasSkill(spring_coming.name) then
                return false
            end
            return player.room:getCurrent() == player and #table.filter(data, function(move)
                return move.toArea == Card.DiscardPile and table.any(move.moveInfo, function(info)
                    return Fk:getCardById(info.cardId).color == Card.Black
                end)
            end) > 0 and #player:getTableMark("@spring_coming") < 2
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local marks = player:getTableMark("@spring_coming")
            for _, move in pairs(data) do
                if move.toArea == Card.DiscardPile then
                    for _, info in pairs(move.moveInfo) do
                        local card = Fk:getCardById(info.cardId)
                        if card.color == Card.Black then
                            table.insertIfNeed(marks, card:getSuitString(true))
                        end
                    end
                end
            end
            room:setPlayerMark(player, "@spring_coming", marks)
            if #marks >= 2 then
                room:setPlayerMark(player, "spring_coming_ready", 1)
                room:addPlayerMark(player, "@spring_interest", 1)
            end
        end,
    })
    spring_coming:addEffect(fk.CardUsing, {
        anim_type = "masochism",
        can_trigger = function(self, event, target, player, data)
            if not player:hasSkill(spring_coming.name) then
                return false
            end
            return table.contains(data.card.skillNames, spring_coming.name) and data.from == player
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            local room = player.room
            room:setPlayerMark(player, "@spring_coming", 0)
        end,
    })
    spring_coming:addEffect(fk.PreCardUse, {
        can_refresh = function(self, event, target, player, data)
            return data.from == player and player:getMark("spring_coming_ready") > 0
        end,
        on_refresh = function(self, event, target, player, data)
            local room = player.room
            local card = Fk:cloneCard(data.card.name)
            card:addSubcard(data.card)
            card.suit = Card.Heart
            card.color = Card.Red
            table.insertIfNeed(card.skillNames, spring_coming.name)
            data.card = card
            room:setPlayerMark(player, "spring_coming_ready", 0)
        end
    })
    extension:loadSkillSkels { spring_notify, spring_interest, spring_coming }
    hy_lilywhite:addSkill("spring_notify")
    hy_lilywhite:addSkill("spring_interest")
    hy_lilywhite:addSkill("spring_coming")
    Fk:loadTranslationTable {
        ["hy_lilywhite"] = "莉莉白",
        ["#hy_lilywhite"] = "春意盎然",
        ["illustrator:hy_lilywhite"] = "かめぱすた",
        ["designer:hy_lilywhite"] = "黑曜人形",
        ["cv:hy_lilywhite"] = "",

        ["spring_notify"] = "告春",
        [":spring_notify"] = "每回合各限一次，在你使用一张♥牌结算结束后，你可以选择一项：1.令一名角色摸两张牌；2.令一名受伤的角色回复1点体力。",
        ["spring_notify_draw"] = "摸两张牌",
        ["spring_notify_recover"] = "回复1点体力",
        ["spring_notify_draw_prompt"] = "告春：令一名角色摸两张牌",
        ["spring_notify_recover_prompt"] = "告春：令一名角色回复1点体力",

        ["spring_interest"] = "春悦",
        [":spring_interest"] = "准备阶段，若你的“春”标记数不小于3，你增加1点体力上限并移除所有“春”。",
        ["@spring_interest"] = "春",
        ["spring_interest_maxHp"] = "增加1点体力上限",
        ["spring_interest_discard"] = "弃置判定区内所有牌。",

        ["spring_coming"] = "春兆",
        [":spring_coming"] = "黑色牌于你的回合内进入弃牌堆后，你记录此牌的花色。在你记录两种花色后，你获得1枚“春”标记，使用的下一张牌视为♥牌且使用时清除花色记录。",
        ["@spring_coming"] = "春兆",
    }
end
